package de.mmis.core.base.abstracttree.serializer.internal;

import java.util.Map;

import de.mmis.core.base.DeserializableAnnotations.DeserializationMethod;
import de.mmis.core.base.abstracttree.InnerNode;
import de.mmis.core.base.abstracttree.Tree;
import de.mmis.core.base.abstracttree.Tree.Type;
import de.mmis.core.base.abstracttree.serializer.AbstractSerializer;
import de.mmis.core.base.abstracttree.serializer.DeserializableException;

/**
 * Serializer class for (de)serializing {@link StackTraceElement}s from/to Trees
 * 
 * @author Christian Koch
 */
public class StackTraceElementSerializer extends
		AbstractSerializer<StackTraceElement> {

	@DeserializationMethod
	public static Object deserialize(Tree[] exp, ClassLoader classLoader,
			String id, Map<String, Object> idmap)
			throws DeserializableException {

		return deserializeStackTraceElement(new InnerNode(exp));
	}

	public static StackTraceElement deserializeStackTraceElement(Tree exp)
			throws DeserializableException {
		if (exp.getType() != Type.INNER
				|| ((InnerNode) exp).getNumberOfSubTrees() != 4)
			throw new DeserializableException(exp,
					"StackTraceElement Tree has to be a struct with 4 elements");

		try {
			return new StackTraceElement(((InnerNode) exp).getSubTree(0)
					.getAsString(), ((InnerNode) exp).getSubTree(1)
					.getAsString(), ((InnerNode) exp).getSubTree(2)
					.getAsString(), ((InnerNode) exp).getSubTree(3).getAsInt());
		} catch (NullPointerException e) {
			throw new DeserializableException(exp, e);
		}
	}

	@Override
	public Tree serializeInternal(StackTraceElement object, boolean explicit,
			Map<Object, String> refmap, ClassLoader classLoader) {
		InnerNode ret = new InnerNode();
		ret.add(Tree.fromObject(object.getClassName(), explicit, refmap,
				classLoader));
		ret.add(Tree.fromObject(object.getMethodName(), explicit, refmap,
				classLoader));
		ret.add(Tree.fromObject(object.getFileName(), explicit, refmap,
				classLoader));
		ret.add(Tree.fromObject(new Integer(object.getLineNumber()), explicit,
				refmap, classLoader));
		return ret;
	}

	@Override
	public String getTypeIdentifier() {
		return "stack-trace-element";
	}
}
